const express = require('express');
const app = express();
app.listen(9000, () => {
  console.log('localhost:9000 服务器启动成功');
});
app.use(express.json());

// 1.终端输入命令npm i jsonwebtoken和npm i express-jwt

// 2.引入生成token字符串模块和解析token字符串模块
const jwt = require('jsonwebtoken');
const {expressjwt: expressJwt} = require('express-jwt');

// 3.定义secret密钥：解密和解密的secret密钥用于防止网络传输过程中token字符串被破解，项目中密钥被书写在public.pub文件中使用fs引入
const secretKey = 'express-jwt';

// 4.生成token字符串
app.post('/middleware_jwt_login', (req, res) => {
  // 验证用户登录信息是否正确
  if (req.body.name !== 'root' || req.body.pwd !== 'root') {
    return res.send('登录失败');
  }
  
  // 生成token字符串
  const token = jwt.sign(req.body, secretKey,
    {
      expiresIn: '60s'// token有效期
    },
  );
  
  // 登陆成功响应
  res.send({
    code: 200,
    msg: '登录成功',
    token: token
  });
});

// 5.注册解析token字符串的中间件，unless用于指定无需Jwt身份验证的路径
app.use(expressJwt({secret: secretKey, algorithms: ['HS256']}).unless({path: [/^\/public\//]}));

// 6.解析token字符串，访问/middleware_jwt_service需添加请求体Authorization，Authorization的值为Bearer Token
app.get('/middleware_jwt_service', (req, res) => {
  console.log('身份认证成功');
  console.log(req.auth); // { name: 'root', pwd: 'root', iat: 1696755429, exp: 1696755459 }
  res.end();
});
app.get('/public/middleware_jwt_service', (req, res) => {
  console.log('跳过身份认证');
  res.end();
});

// 7.注册错误中间件
app.use((error, req, res, next) => {
  // token解析失败产生的错误
  if (error.name === 'UnauthorizedError') {
    console.log('无效Token');
    
    res.send({
      code: 401,
      msg: '无效Token'
    });
  }
  
  // 其他原因导致的错误
  res.send({
    code: 500,
    msg: '未知错误'
  });
});